package br.senac.sp.persistence.unityofwork;

import java.util.List;

import br.senac.sp.persistence.PersistenceFacade;

public class Session {

    private Transaction currentTransaction;

    public Session() {
        //codigo de inicializacao...
        //inicializar mappers
        //inicializar fonte de dados
    }

    public Transaction beginTransaction() {
        if (currentTransaction == null) {
            currentTransaction = new Transaction();
        }
        return currentTransaction;
    }

    public <Entity, OID> Entity get(OID id, Class<Entity> entityType) {
        return PersistenceFacade.getInstance().get(id, entityType);
    }

    public <Entity, OID> List<Entity> get(Class<Entity> entityType) {
        return PersistenceFacade.getInstance().get(entityType);
    }

    public <Entity, OID> void insert(Entity entity) {
        if (currentTransaction != null) {
            currentTransaction.addInsert(entity);
        } else {
            PersistenceFacade.getInstance().put(entity);
        }
    }

    public <Entity, OID> void update(Entity entity) {
        if (currentTransaction != null) {
            currentTransaction.addUpdate(entity);
        } else {
            PersistenceFacade.getInstance().put(entity);
        }
    }

    public <Entity, OID> void remove(Entity entity) {
        if (currentTransaction != null) {
            currentTransaction.addDelete(entity);
        } else {
            PersistenceFacade.getInstance().remove(entity.getClass());
        }
    }

    public void flush() {
        if (currentTransaction != null) {
            currentTransaction.flush();
        }
    }

    public void close() {
        //se nao for feito o flush da sessao ou commit da transaction as operacoes serao perdidas 
        if (currentTransaction != null) {
            currentTransaction = null;
            return;
        }
    }

    /**
     * Pode retornar nulo se nao for feito um beginTransaction antes...
     *
     * @return
     */
    public Transaction getCurrentTransaction() {
        return currentTransaction;
    }

}
